Java 可用于比较与排序的lambda表达式和comparing方法

您所在的位置:网站首页 java compare方法怎么排序的 Java 可用于比较与排序的lambda表达式和comparing方法

Java 可用于比较与排序的lambda表达式和comparing方法

2024-06-18 01:02| 来源: 网络整理| 查看: 265

Java 可用于比较与排序的lambda表达式和comparing方法 温故而知新lambda表达式(parameters) -> { statements; }方式进行比较(parameters) -> expression方式进行比较lambda表达式用于输出 使用comparing()方法进行排序 在上一篇博客中,我介绍了Comparable与Comparator的简单用法,同时也挖坑说要介绍JDK1.8新引入的lambda表达式用来比较,和comparing方法用来比较。这几天学习了一下,将学习笔记记录在本博客中。

温故而知新

首先复原我们上一篇博客中Java 自定义比较与排序方法Comparable与Comparator的简单使用用到的类,和用Compartor接口进行比较: 用到的类:

public class Student { String name; // 学生的姓名 int id; // 学生的学号 double score; // 学生的成绩 Paper p; // 学生发表的论文 Student(String name, int id, double score) { this.name = name; this.id = id; this.score = score; } Student(String name, int id, double score, Paper p) { this.name = name; this.id = id; this.score = score; this.p = p; } } class Paper { char rank; // 论文发表期刊或会议的水平,分'A','B','C'级,'A'类最好,'B'类次之,'C'类最差 double impact_factor; // 论文发表期刊或会议的影响因子 Paper(char rank, double impact_factor) { this.rank = rank; this.impact_factor = impact_factor; } }

使用Compartor进行比较:

import java.util.*; public class Try { public static void main(String[] args) { Paper p1 = new Paper('A', 2.91); Paper p2 = new Paper('B', 1.67); Paper p3 = new Paper('A', 3.89); Student s1 = new Student("Zhang San", 1, 80, p1); Student s2 = new Student("Li Si", 2, 90, p2); Student s3 = new Student("Wang Wu", 3, 70, p3); List l = new LinkedList(); l.add(s1); l.add(s2); l.add(s3); l.sort(new Comparator() { @Override public int compare(Student o1, Student o2) { if (o1.p.rank > o2.p.rank) { // rank越大,论文越差,所以这里是当rank较大时,返回-1,表示论文发得差 return -1; } else if (o1.p.rank return Double.compare(o1.p.impact_factor, o2.p.impact_factor); } } }); System.out.printf("论文发得最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id); System.out.printf("论文发得第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id); System.out.printf("论文发得最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id); } } lambda表达式

lambda表达式是JDK1.8中新添加的一个非常强大功能,它可以用来做比较,也可以实现更厉害的一些功能,一会我们在输出时也可以看到它的强力发挥。 首先介绍一下lambda表达式的语法: (parameters) -> expression 或 (parameters) -> { statements; } 其中,expression是一个表达式,是可以求出值的式子,可以用到在parameters中提到的变量。 {statements;}是一块代码段,在这里实现我们需要的一些功能。要注意的是,如果在statements中用到了外部变量,那么该外部变量必须是由final关键字修饰的。其原理和匿名内部类中使用外部变量必须是由final关键字修饰的类似。

(parameters) -> { statements; }方式进行比较

lambda表达式大大简化了代码,下面我们看一下lambda表达式怎么替代Compartor来进行比较。完整版代码如下,注意观察l.sort()方法的变化:

import java.util.*; public class Try { public static void main(String[] args) { Paper p1 = new Paper('A', 2.91); Paper p2 = new Paper('B', 1.67); Paper p3 = new Paper('A', 3.89); Student s1 = new Student("Zhang San", 1, 80, p1); Student s2 = new Student("Li Si", 2, 90, p2); Student s3 = new Student("Wang Wu", 3, 70, p3); List l = new LinkedList(); l.add(s1); l.add(s2); l.add(s3); l.sort((Student o1, Student o2) -> { if (o1.p.rank > o2.p.rank) { // rank越大,论文越差,所以这里是当rank较大时,返回-1,表示论文发得差 return -1; } else if (o1.p.rank return Double.compare(o1.p.impact_factor, o2.p.impact_factor); } }); System.out.printf("论文发得最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id); System.out.printf("论文发得第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id); System.out.printf("论文发得最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id); } }

输出后可以得到相同的结果:

论文发得最好的人的姓名为Wang Wu,学号为3 论文发得第二好的人的姓名为Zhang San,学号为1 论文发得最差的人的姓名为Li Si,学号为2

在这里我们使用到了(parameters) -> { statements; }这种方式,parameters中我们设置了两个Student对象,在statement中进行了比较方法的实现。

(parameters) -> expression方式进行比较

我们再使用一下(parameters) -> expression这种方式,进行一个简单的比较,比如比较成绩:

import java.util.*; public class Try { public static void main(String[] args) { Paper p1 = new Paper('A', 2.91); Paper p2 = new Paper('B', 1.67); Paper p3 = new Paper('A', 3.89); Student s1 = new Student("Zhang San", 1, 80, p1); Student s2 = new Student("Li Si", 2, 90, p2); Student s3 = new Student("Wang Wu", 3, 70, p3); List l = new LinkedList(); l.add(s1); l.add(s2); l.add(s3); l.sort((Student o1, Student o2) -> Double.compare(o1.score, o2.score)); System.out.printf("成绩最好的人的姓名为%s,学号为%d\n", l.get(2).name, l.get(2).id); System.out.printf("成绩第二好的人的姓名为%s,学号为%d\n", l.get(1).name, l.get(1).id); System.out.printf("成绩最差的人的姓名为%s,学号为%d\n", l.get(0).name, l.get(0).id); } }

输出结果为:

成绩最好的人的姓名为Li Si,学号为2 成绩第二好的人的姓名为Zhang San,学号为1 成绩最差的人的姓名为Wang Wu,学号为3

这就是lambda表达式用于排序的威力,非常简短明了。

lambda表达式用于输出

lambda还有其他很多功能,在这里尝试一下用它改善我们的输出。 我们知道,如果要将一个班级中所有人的成绩都输出,需要使用到循环,其中我们可以使用语法糖for ( : )的结构来简化循环。而对于一个List,lambda方法可以更加简便地使用foreach,比如按照成绩大小从高到低排序输出,示例代码如下:

import java.util.*; public class Try { public static void main(String[] args) { Paper p1 = new Paper('A', 2.91); Paper p2 = new Paper('B', 1.67); Paper p3 = new Paper('A', 3.89); Student s1 = new Student("Zhang San", 1, 80, p1); Student s2 = new Student("Li Si", 2, 90, p2); Student s3 = new Student("Wang Wu", 3, 70, p3); List l = new LinkedList(); l.add(s1); l.add(s2); l.add(s3); l.sort((Student o1, Student o2) -> Double.compare(o2.score, o1.score)); // 改为按成绩非递增排序 System.out.println("将成绩由高到低排序:"); l.forEach((ele) -> System.out.printf("姓名为%s,学号为%d,成绩为%.2f\n", ele.name, ele.id, ele.score)); } }

输出结果为:

将成绩由高到低排序: 姓名为Li Si,学号为2,成绩为90.00 姓名为Zhang San,学号为1,成绩为80.00 姓名为Wang Wu,学号为3,成绩为70.00

可以看到输出时我们用到了lambda表达式,不用写for循环,更方便地进行输出。

使用comparing()方法进行排序

在Compartor接口中有一个方法comparing()也可以进行排序,这也是JDK1.8的新特性。该方法与lambda表达式密切相关。不过我现在查到的资料都是说它只能完成简单规则的比较,而无法实现我们在比较发表论文好坏时,先比较rank,如果相同再比较impact_factor的复杂规则。(如果有大神了解这块内容的话,请多多赐教啊!) 简单地用该方法来实现成绩由高到低的排序:

import java.util.*; public class Try { public static void main(String[] args) { Paper p1 = new Paper('A', 2.91); Paper p2 = new Paper('B', 1.67); Paper p3 = new Paper('A', 3.89); Student s1 = new Student("Zhang San", 1, 80, p1); Student s2 = new Student("Li Si", 2, 90, p2); Student s3 = new Student("Wang Wu", 3, 70, p3); List l = new LinkedList(); l.add(s1); l.add(s2); l.add(s3); l.sort(Comparator.comparing(o -> -o.score)); // 由于默认的是从低到高,我们加个负号,就能实现从高到低 System.out.println("将成绩由高到低排序:"); l.forEach((ele) -> System.out.printf("姓名为%s,学号为%d,成绩为%.2f\n", ele.name, ele.id, ele.score)); } }

输出结果为:

将成绩由高到低排序: 姓名为Li Si,学号为2,成绩为90.00 姓名为Zhang San,学号为1,成绩为80.00 姓名为Wang Wu,学号为3,成绩为70.00

个人觉得这两个JDK1.8的新特性挺好的,尤其是lambda表达式,它让Java有了函数式编程的风格(有Python内味了~)。lambda表达式还有更多内容和有趣的用例,都值得去深入学习。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3